<!-- 创建时间: 2021年06月27日 星期天 16:41 -->
<template>
    <div class="itemAnalysis_container">
        <!-- 分割线，显示标题信息 -->
        <el-divider content-position="left">{{ data.className }}【{{ data.coursesName }}】试题分析</el-divider>
        <!-- 返回上一页内容 -->
        <div class="itemAnalysis"
             @click="itemAnalysis">返回上一页</div>
        <!-- Container 布局容器 -->
        <el-container :style="{ height: el_containerHeight + 'px', border: '1px solid #eee',}"
                      ref="el_container">
            <!-- <el-aside>：侧边栏容器。 -->
            <el-aside style="background-color: rgb(238, 241, 246); padding: 0 5px;">
                <div class="elasideInfo">
                    <span>题量:{{ totalQuestion }}</span>
                    <span>总分:{{ totalScore }}</span>
                </div>
                <div class="questionList"
                     :class="{ active: index == clickIndex }"
                     @click="clickIndex = index"
                     v-for="(item, index) in questionsList"
                     :key="index">
                    <el-row>
                        <el-col class="questionList_questionName">{{ item.questionName }}
                        </el-col>
                        <el-col class="questionList_accuracy"
                                :style="{ color: item.accuracyTextColor }">{{ item.people }}/{{ data.classPeopleNumber }}人已作答(正确率{{ item.accuracy }})</el-col>
                    </el-row>
                </div>
            </el-aside>
            <el-container>
                <!-- <el-main>：主要区域容器。 -->
                <el-main>
                    <!-- 试题信息 -->
                    <el-card class="box-card">
                        <div slot="header"
                             class="clearfix">
                            <span>
                                <el-tag type="success">{{ questionsList[clickIndex]["typeLatter"] }}</el-tag>
                                <span class="header_clearfix_info">
                                    No:{{ questionsList[clickIndex]["id"] }}&nbsp;&nbsp;&nbsp; 分值:{{questionsList[clickIndex]["score"] }}
                                </span>
                                <br /> {{ questionsList[clickIndex]["questionName"] }}
                            </span>
                        </div>
                        <div style="margin-bottom: 10px;"
                             v-for="(item, index) in questionsList[clickIndex]['optionList']"
                             :key="index">
                            {{ questionsList[clickIndex]["abcd"][index] }}.&nbsp;&nbsp;{{ item }}
                        </div>
                        <span>
                            正确答案:{{ questionsList[clickIndex]["rightOptionLetter"] }}
                        </span>
                    </el-card>
                    <!-- echerts图表 -->
                    <div style="width: 100%;height: 400px"
                         id="echarts">
                        <span v-if="answerList[0].studentNumber == ''">暂无数据</span>
                    </div>
                    <!-- 正确、错误、缺答名单 -->
                    <el-collapse v-model="activeNames">
                        <el-collapse-item :title="'正确名单 ' + correctList.length"
                                          name="1">
                            <div class="listParentStyle">
                                <div v-for="(item, index) in correctList"
                                     :key="index"
                                     class="correntListStyle">
                                    <el-avatar icon="el-icon-user-solid"></el-avatar>
                                    <span>{{ item.studentName }}</span>
                                    <span>{{ item.studentNumber }}</span>
                                </div>
                                <span v-if="correctList.length == 0">暂无数据</span>
                            </div>
                        </el-collapse-item>
                        <el-collapse-item :title="'错误名单 ' + errorList.length"
                                          name="2">
                            <div class="listParentStyle">
                                <el-badge v-for="(item, index) in errorList"
                                          :key="index"
                                          :value="item.errorAnswer"
                                          style="margin: 10px 20px 0px 0px;">
                                    <div class="correntListStyle item">
                                        <el-avatar icon="el-icon-user-solid"></el-avatar>
                                        <span>{{ item.studentName }}</span>
                                        <span>{{ item.studentNumber }}</span>
                                    </div>
                                </el-badge>
                                <span v-if="errorList.length == 0">暂无数据</span>
                            </div>
                        </el-collapse-item>
                        <el-collapse-item :title="'未答名单 ' + unAnsweredList.length"
                                          name="3">
                            <div class="listParentStyle">
                                <div v-for="(item, index) in unAnsweredList"
                                     :key="index"
                                     class="correntListStyle">
                                    <el-avatar icon="el-icon-user-solid"></el-avatar>
                                    <span>{{ item.studentName }}</span>
                                    <span>{{ item.studentNumber }}</span>
                                </div>
                                <span v-if="unAnsweredList.length == 0">暂无数据</span>
                            </div>
                        </el-collapse-item>
                    </el-collapse>
                </el-main>
            </el-container>
        </el-container>
    </div>
</template>

<script>
//这里可以导入其他文件（比如：组件，工具js，第三方插件js，json文件，图片文件等等）
//例如：import 《组件名称》 from '《组件路径》';
import $ from "jquery";
var echarts = require("echarts");
import "../../js/echartsStyle";
import localforage from "localforage";

export default {
    //import引入的组件需要注入到对象中才能使用
    components: {},
    data () {
        //这里存放数据
        return {
            data: {
                className: "",
                classNumber: "",
                classPeopleNumber: "",
                coursesName: "",
                questionBank: "",
            },
            el_containerHeight: "",
            questionsList: [{
                id: "",
                optionList: "",
                questionName: "",
                rightOption: "",
                score: "",
                type: "",
            },],
            answerList: [{
                rightOption: "",
                studentNumber: "",
            },],
            clickIndex: 0,
            totalScore: 0,
            totalQuestion: 0,
            activeNames: ["1"],
            isDrawEchertsFlag: false,
            allStudent: [],
            studentInfo: [],
            correctList: [],
            errorList: [],
            unAnsweredList: [],
            letterList: ["A", "B", "C", "D", "E", "F", "H", "I", "J", "K"], // 字第列表
        };
    },
    //监听属性 类似于data概念
    computed: {},
    //监控data中的数据变化
    watch: {
        clickIndex: function (val) {
            this.drawEchertsData();
            this.getCorrectList();
        },
    },
    //方法集合
    methods: {
        // 返回上一页
        itemAnalysis () {
            this.$router.push({
                name: "checkStudentResult",
                params: {
                    data: JSON.stringify(this.data)
                },
            });
        },
        // 获取试题库
        getQuestion () {
            return new Promise((resolve) => {
                this.$http
                    .post("getQuestion", {
                        tableName: this.data.questionBank,
                    })
                    .then((res) => {
                        this.clacGetQuestionResponse(res, resolve);
                    })
                    .catch((err) => {
                        this.$message({
                            message: err,
                            type: "error",
                        });
                        this.$router.push("/teacher/coursesClass");
                    });
            });
        },
        // 计算试题的总分与总量
        clacGetQuestionResponse (res, resolve) {
            res.body.forEach((value, index) => {
                // 将选项字符串转换为数组
                value.optionList = value.optionList.split("&");
                // 为选项配置对应个数的ABCD
                let abcd = ["A", "B", "C", "D", "E", "F", "G"];
                // 获取与选项对应个数的字母
                value.abcd = this.letterList.slice(0, value.optionList.length);
                // 获取对正确答案对应的字母
                switch (value.type) {
                    case "radio":
                        value.rightOptionLetter =
                            this.letterList[value.optionList.indexOf(value.rightOption)];
                        value.typeLatter = "单选";
                        break;
                    case "checkbox":
                        value.rightOption = value.rightOption.split("&");
                        value.rightOptionLetter = "";
                        for (let i = 0; i < value.rightOption.length; i++) {
                            value.rightOptionLetter += value.abcd[value.optionList.indexOf(value.rightOption[i])]
                        }
                        value.typeLatter = "多选";
                        break;
                    default:
                        break;
                }
                // 计算总分
                this.totalScore += value.score;
                // 计算总题量
                this.totalQuestion++;
            });
            this.questionsList = res.body;
            resolve(true);
        },
        // 获取作答库
        getAnswerLibrary () {
            return new Promise((resolve) => {
                let answer =
                    this.data.classNumber + "-" + this.data.questionBank;
                this.$http
                    .post("getAnswerLibrary", {
                        classNumber: this.data.classNumber,
                        questionBank: answer,
                    })
                    .then((res) => {
                        if (res.body == "") {
                            for (
                                let i = 0; i < this.questionsList.length; i++
                            ) {
                                this.questionsList[i]["people"] = 0;
                                this.questionsList[i]["accuracy"] = 0 + "%";
                            }
                            this.$message.warning("本场考试无作答记录");
                            return;
                        }
                        res.body.forEach((value, index) => {
                            value.rightOption = JSON.parse(value.rightOption);
                        });
                        this.answerList = res.body;
                        this.isDrawEchertsFlag = true;
                        // 计算试题作答人数 及 正确率
                        this.calculationSubjectAccuracy(resolve);
                    })
                    .catch((err) => {
                        this.$message({
                            message: err,
                            type: "error",
                        });
                    });
            });
        },

        // 计算试题正确率 及 作答人数
        calculationSubjectAccuracy (resolve) {
            // ======================计算每题已作答人数======================
            for (let i = 0; i < this.questionsList.length; i++) {
                let people = 0; //存储人数
                let accuracy = 0; //存储正确数
                for (let j = 0; j < this.answerList.length; j++) {
                    if (
                        this.answerList[j]["rightOption"][
                        this.questionsList[i]["id"] - 1
                        ][0] == this.questionsList[i]["id"]
                    ) {
                        people++;
                        // ======================计算每题正确率======================
                        // ======================可扩展题型方式，添加case语句即可======================
                        switch (this.questionsList[i]["type"]) {
                            case "radio":
                                accuracy = accuracy + this.calculationSubjectAccuracy_radio(this.answerList[j], this.questionsList[i]);
                                break;
                            case "checkbox":
                                accuracy += this.calculationSubjectAccuracy_checkbox(this.answerList[j], this.questionsList[i]);
                                break;
                            default:
                                break;
                        }
                    }
                }
                this.questionsList[i]["people"] = people;
                // this.questionsList[i]['accuracy'] = (accuracy / this.data.classPeopleNumber).toFixed(2)*100+"%";//除班级总人数
                this.questionsList[i]["accuracy"] =
                    (accuracy / people).toFixed(2) * 100 + "%"; //除已作答人数
                this.questionsList[i][
                    "accuracyTextColor"
                ] = this.setAccuracyTextColor(
                    (accuracy / people).toFixed(2) * 100
                );
            }
            resolve(true);
            this.$forceUpdate();
        },
        /**
         *  {…}
                rightOption: Array(50)
                studentName: "王彦钧"
                studentNumber: "2006831514"

            {…}
                abcd: Array(4)
                accuracy: "0%"
                accuracyTextColor: "#ff6347"
                id: 1
                optionList: Array(4)
                people: 2
                questionName: "5+2=( )"
                rightOption: "7"
                rightOptionLetter: "B"
                score: 2
                type: "radio"
                typeLatter: "单选"
         */
        calculationSubjectAccuracy_radio (answerList, questionList) {
            if (answerList.rightOption[questionList.id - 1][1] == questionList.rightOption) {
                return 1
            } else {
                return 0;
            }
        },
        /**
         * {…}
            rightOption: Array(2)
                0: (2) [1, "如果源文件包含import语句，则该语句必须是除空行和注释行外的第一个语句行。&如果某公共接口被声明在一个源文件中，则接口必须与源文件具有相同名字。"]
                1: (2) [2, "接口中的方法必定是抽象方法，但可以不用关键字abstract修饰。&如果某源文件包含package语句，则该语句必须是第一个非空、非注释行。"]
            studentName: "王彦钧"
            studentNumber: "2006831514"
            
            {…}
            abcd: Array(4)
            accuracy: "NaN%"
            accuracyTextColor: "#ff6347"
            id: 1
            optionList: Array(4)
            people: 1
            questionName: "下面说法正确的是()"
            rightOption: Array(2)
                0: "如果某公共接口被声明在一个源文件中，则接口必须与源文件具有相同名字。"
                1: "如果源文件包含import语句，则该语句必须是除空行和注释行外的第一个语句行。"
            rightOptionLetter: (...)
            score: 3
            type: "checkbox"
            typeLatter: "多选"
         */
        calculationSubjectAccuracy_checkbox (answerList, questionList) {
            answerList.rightOption[questionList.id - 1][1] = answerList.rightOption[questionList.id - 1][1].split("&");
            let stuRightOption = answerList.rightOption[questionList.id - 1][1];
            if (stuRightOption.length != questionList.rightOption.length) return 0;
            let flag = true;
            for (let i = 0; i < stuRightOption.length && flag; i++) {
                for (let j = 0; j < questionList.rightOption.length; j++) {
                    if (stuRightOption[i] == questionList.rightOption[j]) {
                        flag = true;
                        break;
                    }
                    flag = false;
                }
            }
            if (flag) return 1;
            return 0;
        },
        // 设置正确和错误人员名单
        setCorrectList () {

        },
        // 设置试题正确率文本的相应颜色
        setAccuracyTextColor (accuracy) {
            if (accuracy >= 70) {
                return "#67c23a";
            } else if (accuracy >= 50) {
                return "#E6A23C";
            } else {
                return "#ff6347";
            }
        },
        // 绘制答案分布echarts图表
        drawEcherts (xAxisData, data) {
            let myChart = echarts.init(
                document.getElementById("echarts"),
                "macarons"
            );
            let option = {
                title: {
                    text: "答案分布",
                },
                tooltip: {},
                xAxis: {
                    type: "category",
                    data: xAxisData,
                },
                yAxis: {
                    type: "value"
                },
                series: [{
                    type: "bar",
                    data: data,
                    barWidth: 60,
                    emphasis: {
                        focus: "series",
                    },
                    animationDelay: function (idx) {
                        return idx * 100;
                    },
                },],
                animationEasing: "elasticOut",
            };
            myChart.setOption(option);
        },
        // echerts图表数据
        drawEchertsData () {
            this.el_containerHeight =
                window.innerHeight - this.$refs.el_container.$el.offsetTop - 20;
            let xAxisData = this.questionsList[this.clickIndex]["abcd"];
            // 统计出 该试题的选项选择情况 既 每项有多少人选择
            let data = new Array(xAxisData.length).fill(0);
            for (let i = 0; i < this.answerList.length; i++) {
                // console.log(this.answerList[i]['rightOption'][this.questionsList[this.clickIndex]["id"] - 1]);//重要日志，匆删除
                let type = this.questionsList[this.clickIndex]['type'];
                let stures = this.answerList[i]["rightOption"][
                    this.questionsList[this.clickIndex]["id"] - 1
                ][1];
                switch (type) {
                    case "radio":
                        let questionIndex = this.questionsList[this.clickIndex][
                            "optionList"
                        ].indexOf(stures);
                        data[questionIndex] = data[questionIndex] + 1;
                        break;
                    case "checkbox":
                        for (let j = 0; j < stures.length; j++) {
                            let questionIndex = this.questionsList[this.clickIndex]['optionList'].indexOf(stures[j]);
                            data[questionIndex] = data[questionIndex] + 1;
                        }
                        break;
                    default:
                        break;
                }

                // console.log(stures, questionIndex, xAxisData[questionIndex]);//重要日志，匆删除
            }
            this.drawEcherts(xAxisData, data);
        },
        // 正确名单/错误名单
        getCorrectList () {
            this.correctList = [];
            this.errorList = [];
            let currentQuestionIndex =
                this.questionsList[this.clickIndex]["id"] - 1,
                currentQuestionRightOption = this.questionsList[
                    this.clickIndex
                ]["rightOption"],
                currentQuestionType = this.questionsList[this.clickIndex]['type'];
            for (let i = 0; i < this.answerList.length; i++) {
                switch (currentQuestionType) {
                    case "radio":
                        this.getCorrectList_radio(this.answerList[i], currentQuestionIndex, currentQuestionRightOption);
                        break;
                    case "checkbox":
                        this.getCorrectList_checkbox(this.answerList[i], currentQuestionIndex, currentQuestionRightOption);
                        break;
                    default:
                        break;
                }
            }
        },
        setCorrect (studentName, studentNumber, errorAnswer, flag) {
            if (flag) {
                this.correctList.push({
                    studentNumber: studentNumber,
                    studentName: studentName,
                });
            } else {
                this.errorList.push({
                    studentNumber: studentNumber,
                    studentName: studentName,
                    errorAnswer: errorAnswer
                });
            }
        },
        getCorrectList_radio (answerList, currentQuestionIndex, currentQuestionRightOption) {
            if (answerList.rightOption[currentQuestionIndex][1] == currentQuestionRightOption) {
                this.setCorrect(answerList.studentName, answerList.studentNumber, null, true);
            } else {
                let errorAnswer = this.questionsList[this.clickIndex].abcd[
                    this.questionsList[this.clickIndex][
                        "optionList"
                    ].indexOf(
                        answerList.rightOption[
                        currentQuestionIndex
                        ][1]
                    )
                ];
                this.setCorrect(answerList.studentName, answerList.studentNumber, errorAnswer, false);
            }
        },
        getCorrectList_checkbox (answerList, currentQuestionIndex, currentQuestionRightOption) {
            let list = answerList.rightOption[currentQuestionIndex][1];
            let flag = true;
            if (list.length != currentQuestionRightOption.length) flag = false;
            for (let i = 0; i < list.length && flag; i++) {
                for (let j = 0; j < currentQuestionRightOption.length; j++) {
                    if (list[i] == currentQuestionRightOption[j]) {
                        flag = true;
                        break;
                    }
                    flag = false;
                }
            }
            if (flag) {
                this.setCorrect(answerList.studentName, answerList.studentNumber, null, true);
            } else {
                let errorAnswer = "";
                for (let i = 0; i < list.length; i++) {
                    for (let j = 0; j < currentQuestionRightOption.length; j++) {
                        if (list[i] == currentQuestionRightOption[j]) {
                            errorAnswer += this.letterList[j];
                        }
                    }
                }
                this.setCorrect(answerList.studentName, answerList.studentNumber, errorAnswer, false);
            }
        },
        // 未答名单
        getUnAnsweredList () {
            let correctList = JSON.parse(JSON.stringify(this.correctList));
            let errorList = JSON.parse(JSON.stringify(this.errorList));
            let allStudent = JSON.parse(JSON.stringify(this.allStudent));
            let newlist = correctList.concat(errorList);
            for (let i = 0; i < newlist.length; i++) {
                for (let j = 0; j < allStudent.length; j++) {
                    if (
                        newlist[i]["studentNumber"] ==
                        allStudent[j]["studentNumber"]
                    ) {
                        allStudent.splice(j, 1);
                    }
                }
            }
            this.unAnsweredList = allStudent;
        },
    },
    //生命周期 - 创建完成（可以访问当前this实例）
    created () {
        if (this.$route.params.data != undefined) {
            localStorage.setItem(
                "itemAnalysis",
                JSON.stringify(this.$route.params.data)
            );
            localforage.setItem("allStudent", this.$route.params.allStudent);
        }
        let data = JSON.parse(localStorage.getItem("itemAnalysis"));
        if (data == null) {
            this.$router.push("/teacher/coursesClass");
            this.$message({
                message: "数据异常，返回首页",
                type: "error",
            });
            return;
        }
        this.data = data;
        let dt = setInterval(() => {
            localforage.getItem("allStudent").then((res) => {
                if (res != null) {
                    this.allStudent = res;
                    this.getUnAnsweredList();
                    clearInterval(dt);
                }
            });
        }, 200);

        this.$once("hook:beforeDestroy", () => {
            clearInterval(dt);
        });
        this.getQuestion()
            .then((res) => {
                return this.getAnswerLibrary();
            })
            .then((res) => {
                this.getCorrectList();
            });
    },
    beforeDestroy () {
        localStorage.removeItem("itemAnalysis");
        localforage.removeItem("allStudent");
    },
    //生命周期 - 挂载完成（可以访问DOM元素）
    mounted () {
        let dt = setInterval(() => {
            if (this.isDrawEchertsFlag) {
                this.drawEchertsData();
                clearInterval(dt);
            }
        }, 200);
        this.$once("hook:beforeDestroy", () => {
            clearInterval(dt);
        });
    },
    //当data中定义的数据有变化时就会加载updated方法
    updated () { },
};
</script>

<style lang="scss" scoped>
//@import url(); 引入公共css类
.itemAnalysis_container {
    .itemAnalysis {
        display: flex;
        justify-content: flex-end;
        padding: 0 20px;
        cursor: pointer;
        color: #409eff;
    }

    .itemAnalysis:hover {
        color: red;
        text-decoration: underline;
    }

    .elasideInfo {
        color: #ff6347;
        font-weight: bold;
        background: #aeeef1;
        padding: 1em;
        display: flex;
        justify-content: space-evenly;
    }

    .questionList {
        height: 60px;
        display: flex;
        align-items: center;
        cursor: pointer;
        padding-left: 10px;
        color: #3e3b3b;

        &:hover {
            box-shadow: 0px 0px 4px 0px #afa9a9;
        }

        .questionList_questionName {
        }

        .questionList_accuracy {
            font-size: 12px;
            color: #ff6347;
        }
    }

    .active {
        background-image: linear-gradient(to left, #aeeef1, #fff);
    }

    .box-card {
        color: #3e3b3b;
        font-size: 20px;

        .clearfix {
            .header_clearfix_info {
                color: #67c23a;
                margin-left: 10px;
                font-size: 13px;
            }
        }
    }

    #echarts span {
        display: flex;
        height: 100%;
        justify-content: center;
        align-items: center;
        color: darkgray;
    }

    .listParentStyle {
        display: flex;
        padding: 5px;

        .correntListStyle {
            border: 1px solid transparent;
            padding: 5px;
            width: 100px;
            display: flex;
            flex-direction: column;
            align-items: center;
            user-select: none;

            &:hover {
                box-shadow: 0px 0px 4px 1px #e2dfdf;
            }
        }
    }
}
</style>
